package com.efast.dmom.mes.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.efast.dmom.mes.bean.ResultBean;
import com.efast.dmom.mes.bean.WmsAllocationOrder;
import com.efast.dmom.mes.bean.WmsAllocationOrderLog;
import com.efast.dmom.mes.bean.WmsOrderLog;
import com.efast.dmom.mes.bean.WmsStorage;
import com.efast.dmom.mes.dao.entity.PartDao;
import com.efast.dmom.mes.dao.entity.WmsAllocationOrderDao;
import com.efast.dmom.mes.dao.entity.WmsAllocationOrderLogDao;
import com.efast.dmom.mes.dao.entity.WmsOrderLogDao;
import com.efast.dmom.mes.dao.entity.WmsStorageDao;
import com.efast.dmom.mes.entity.PartEntity;
import com.efast.dmom.mes.entity.WmsWarehouseBasEntity;
import com.efast.dmom.mes.service.WmsAllocationOrderService;
import com.efast.dmom.mes.util.ServiceBaseEntityUtil;
import com.efast.dmom.mes.util.TimeUtil;
import com.efast.dmom.mes.util.WmsOrderLogStatus;
import com.efast.dmom.mes.util.WmsOrderStatusUtil;

@Service
@Transactional
public class WmsAllocationOrderServiceImpl implements WmsAllocationOrderService {

	// 调拨单
	@Autowired
	private WmsAllocationOrderDao wmsAllocationOrderDao;

	// 调拨单日志
	@Autowired
	private WmsAllocationOrderLogDao wmsAllocationOrderLogDao;

	// 工单操作日志
	@Autowired
	private WmsOrderLogDao wmsOrderLogDao;

	// 仓储
	@Autowired
	private WmsStorageDao wmsStorageDao;

	@Autowired
	private ServiceBaseEntityUtil serviceBaseEntityUtil;
	@Autowired
	private PartDao partDao;

	@Override
	public ResultBean batchSave(List<WmsAllocationOrder> list) {
		ResultBean resultBean = new ResultBean(true);
		String no = serviceBaseEntityUtil.getNo("DBD_code");
		list.forEach(item -> {
			item.setAllocationOrderNo(no);
			ServiceBaseEntityUtil.setSaveBaseEntityData(item);
			item.setAllocationStatus(WmsOrderStatusUtil.NOCONFIRM);
			if (item.getAllocationType().equals("委外")) {
				item.setTotalWeight(item.getUnitWeight() * item.getAllocationQuality());
			}
		});
		// 保存调拨单数据
		wmsAllocationOrderDao.batchSave(list);

		// 保存调拨单操作日志
		saveOrderLog(list, WmsOrderLogStatus.ADD.getOperation());
		return resultBean;
	}

	@Override
	public ResultBean update(WmsAllocationOrder wmsAllocationOrder) {
		ResultBean resultBean = new ResultBean(true);
		// 查询是否编辑更改的id和已存在的id冲突
		List<WmsAllocationOrder> selectByNos = wmsAllocationOrderDao.selectByNos(wmsAllocationOrder);
		for (WmsAllocationOrder wmsAllocationOrder2 : selectByNos) {
			if (wmsAllocationOrder2.getPartId() == wmsAllocationOrder.getPartId()
					&& wmsAllocationOrder2.getId() != wmsAllocationOrder.getId()) {
//					resultBean.setErrorMessage("编辑更改的物料和已存在物料冲突！");
//					return resultBean;
			}
		}

		if (!selectByNos.get(0).getAllocationType().equals(wmsAllocationOrder.getAllocationType())) {
			resultBean.setErrorMessage("编辑更改的物料类型和已存在物料类型冲突！");
			return resultBean;
		}
		ServiceBaseEntityUtil.setUpdateBaseEntityData(wmsAllocationOrder);
		if (wmsAllocationOrder.getAllocationType().equals("委外")) {
			wmsAllocationOrder
					.setTotalWeight(wmsAllocationOrder.getAllocationQuality() * wmsAllocationOrder.getUnitWeight());
		}
		// 更新调拨单数据
		wmsAllocationOrderDao.update(wmsAllocationOrder);

		// 保存编辑时操作日志
		List<WmsAllocationOrder> list = new ArrayList<WmsAllocationOrder>();
		list.add(wmsAllocationOrder);
		saveOrderLog(list, WmsOrderLogStatus.UPDATE.getOperation());
		return resultBean;
	}

	@Override
	public ResultBean batchDelete(List<WmsAllocationOrder> selectByNoList) {
		ResultBean resultBean = new ResultBean(true);
		List<WmsAllocationOrder> list = wmsAllocationOrderDao.selectByNoList(selectByNoList);
		// 删除调拨单数据
		wmsAllocationOrderDao.batchDelete(list);

		// 保存操作日志
		saveOrderLog(list, WmsOrderLogStatus.UPDATE.getOperation());
		return resultBean;
	}

	@Override
	public ResultBean batchConfirm(List<WmsAllocationOrder> selectByNoList) throws RuntimeException {
		ResultBean resultBean = new ResultBean(true);
		List<WmsAllocationOrder> list = wmsAllocationOrderDao.selectByNoList(selectByNoList);
		list.forEach(item -> {
			item.setAllocationStatus(WmsOrderStatusUtil.CONFIRM);
			item.setAllocationTime(TimeUtil.getLocalDateTime());
		});

		// 批量确认调拨数据
		int batchConfirm = wmsAllocationOrderDao.batchConfirm(list);

		if (batchConfirm > 0) {
			// 调拨时更新库存数据
			ResultBean updateStorageQuality = updateStorageQuality(list);
			if (!updateStorageQuality.success) {
				return updateStorageQuality;
			}

			// 保存操作日志
			saveOrderLog(list, WmsOrderLogStatus.CONFIRM.getOperation());

			// 保存调拨日志
			List<WmsAllocationOrderLog> allocationLogList = new ArrayList<WmsAllocationOrderLog>();
			list.forEach(item -> {
				WmsAllocationOrderLog wmsAllocationOrderLog = new WmsAllocationOrderLog();
				wmsAllocationOrderLog.setAllocationId(item.getId());
				wmsAllocationOrderLog.setFromWarehouseId(item.getFromWarehouseId());
				wmsAllocationOrderLog.setToWarehouseId(item.getToWarehouseId());
				wmsAllocationOrderLog.setPartId(item.getPartId());
				wmsAllocationOrderLog.setAllocationNo(item.getAllocationOrderNo());
				wmsAllocationOrderLog.setAllocationQuality(item.getAllocationQuality());
				ServiceBaseEntityUtil.setUpdateBaseEntityData(wmsAllocationOrderLog);
				allocationLogList.add(wmsAllocationOrderLog);
			});
			wmsAllocationOrderLogDao.batchSave(allocationLogList);
		} else {
		}

		return resultBean;
	}

	// 保存调拨单操作日志数据
	private void saveOrderLog(List<WmsAllocationOrder> list, String operationType) {
		List<WmsOrderLog> logList = new ArrayList<WmsOrderLog>();
		list.forEach(item -> {
			WmsOrderLog wmsOrderLog = new WmsOrderLog();
			wmsOrderLog.setOrderId(item.getPartId());
			wmsOrderLog.setOrderOperationStatus(operationType);
			wmsOrderLog.setOrderNo(item.getAllocationOrderNo());
			ServiceBaseEntityUtil.setUpdateBaseEntityData(wmsOrderLog);
			wmsOrderLog.setOrderId(item.getId());
			logList.add(wmsOrderLog);
		});
		wmsOrderLogDao.batchSave(logList);

	}

	// 调拨时更新库存数据
	public ResultBean updateStorageQuality(List<WmsAllocationOrder> list) {
		ResultBean resultBean = new ResultBean(true);
		// 更新库存的集合
		List<WmsStorage> storageList = new ArrayList<WmsStorage>();
		// 新增库存的集合
		List<WmsStorage> saveStorageList = new ArrayList<WmsStorage>();
		for (WmsAllocationOrder wmsAllocationOrder : list) {
			WmsStorage wmsStorage = new WmsStorage();
			wmsStorage.setPartId(wmsAllocationOrder.getPartId());
			wmsStorage.setWarehouseBasId(wmsAllocationOrder.getFromWarehouseId());
			List<WmsStorage> selectByWarehouseAndPart = wmsStorageDao.selectByWarehouseAndPart(wmsStorage);
			// 调拨的总金额
			double sum = wmsAllocationOrder.getUnitPrice() * wmsAllocationOrder.getAllocationQuality();
			// 当仓库类型是外协仓库时库存重量
			WmsWarehouseBasEntity byId = wmsStorageDao.getById(wmsAllocationOrder.getToWarehouseId());
			PartEntity byId2 = partDao.getById(wmsAllocationOrder.getPartId());
			if (byId.getWarehouseType().equals("外协仓库")&& byId2.getIsWeightUnit().equals("是")) {
				wmsAllocationOrder.setTotalWeight(wmsAllocationOrder.getAllocationQuality() * wmsAllocationOrder.getUnitWeight());
			}
			if (selectByWarehouseAndPart.size() == 0) {
				// 当操作失败事务手动回滚
				throw new RuntimeException("仓库/ " + wmsAllocationOrder.getWarehouseName() + "/ 中无法找到当前仓库对应的物料/"
						+ wmsAllocationOrder.getPartName() + "/！");
//				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//				return resultBean.setErrorMessage("仓库"+wmsAllocationOrder.getWarehouseName()+"中无法找到当前仓库对应的物料！"+wmsAllocationOrder.getPartName());
			} else {
				WmsStorage wmsStorage2 = selectByWarehouseAndPart.get(0);
				if (wmsStorage2.getStorageQuality() < wmsAllocationOrder.getAllocationQuality()) {
					// 当操作失败事务手动回滚
					throw new RuntimeException("仓库/" + wmsAllocationOrder.getWarehouseName() + "/数量少于调拨数量");
//					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//					return resultBean.setErrorMessage("仓库"+wmsAllocationOrder.getWarehouseName()+"数量少于调拨数量");
				} else {

					if (wmsStorage2.getTotalAmount()
							- wmsAllocationOrder.getUnitPrice() * wmsAllocationOrder.getAllocationQuality() < 0) {
						throw new RuntimeException("源仓库总金额少于调拨金额");
					}
					// 当满足是扣减对应库存并且同时对目的仓库新增库存
					wmsStorage2.setStorageQuality(
							wmsStorage2.getStorageQuality() - wmsAllocationOrder.getAllocationQuality());
					wmsStorage2.setTotalAmount(wmsStorage2.getTotalAmount() - sum);
					// 扣减对应重量
					WmsWarehouseBasEntity byId3 = wmsStorageDao.getById(wmsAllocationOrder.getFromWarehouseId());
					if (byId3.getWarehouseType().equals("外协仓库")&& byId2.getIsWeightUnit().equals("是")) {
						wmsStorage2.setTotalWeight(wmsStorage2.getTotalWeight() - wmsAllocationOrder.getTotalWeight());
					}
					ServiceBaseEntityUtil.setUpdateBaseEntityData(wmsStorage2);
					// 扣减库存
					storageList.add(wmsStorage2);
					// 当库存表中没有库存对应的物料时，在库存表中新增一条，当存在，更新库存
					WmsStorage toWmsStorage = new WmsStorage();
					toWmsStorage.setPartId(wmsAllocationOrder.getPartId());
					toWmsStorage.setWarehouseBasId(wmsAllocationOrder.getToWarehouseId());
					List<WmsStorage> selectByWarehouseAndPart2 = wmsStorageDao.selectByWarehouseAndPart(toWmsStorage);
					// 对目的仓库新增库存
					if (selectByWarehouseAndPart2.size() > 0) {
						WmsStorage wmsStorage3 = selectByWarehouseAndPart2.get(0);
						wmsStorage3.setStorageQuality(
								wmsStorage3.getStorageQuality() + wmsAllocationOrder.getAllocationQuality());
						wmsStorage3.setTotalAmount(wmsStorage3.getTotalAmount() + sum);
						wmsStorage3.setTotalWeight(wmsStorage3.getTotalWeight() + wmsAllocationOrder.getTotalWeight());
						ServiceBaseEntityUtil.setUpdateBaseEntityData(wmsStorage3);
						storageList.add(wmsStorage3);
					} else {
						WmsStorage wmsStorage3 = new WmsStorage();
						wmsStorage3.setPartId(wmsAllocationOrder.getPartId());
						wmsStorage3.setWarehouseBasId(wmsAllocationOrder.getToWarehouseId());
						wmsStorage3.setStorageQuality(wmsAllocationOrder.getAllocationQuality());
						wmsStorage3.setUnit(wmsAllocationOrder.getUnit());
						wmsStorage3.setTotalAmount(sum);
						wmsStorage3.setTotalWeight(wmsAllocationOrder.getTotalWeight());
						ServiceBaseEntityUtil.setSaveBaseEntityData(wmsStorage3);
						saveStorageList.add(wmsStorage3);
					}
				}
			}
		}
		// 更新出库和入库的库存数据
		wmsStorageDao.batchUpdateQuality(storageList);
		// 当调拨过去的仓库没有对应物料，则新增一条数据
		if (saveStorageList.size() > 0) {
			wmsStorageDao.batchSave(saveStorageList);
		}
		return resultBean;
	}

	@Override
	public ResultBean save(WmsAllocationOrder wmsAllocationOrder) {
		ResultBean resultBean = new ResultBean(true);
		List<WmsAllocationOrder> selectByNos = wmsAllocationOrderDao.selectByNos(wmsAllocationOrder);
		if (selectByNos.size() > 0) {
			for (WmsAllocationOrder wmsAllocationOrder2 : selectByNos) {
				if (wmsAllocationOrder2.getPartId() == wmsAllocationOrder.getPartId()) {
//					resultBean.setErrorMessage("当前新增物料已存在，请检查！");
//					return resultBean;
				}
				if (!wmsAllocationOrder2.getAllocationType().equals(wmsAllocationOrder.getAllocationType())) {
					resultBean.setErrorMessage("当前物料类型必须为/" + wmsAllocationOrder2.getAllocationType() + "/请检查！");
					return resultBean;
				}
			}
		}
		ServiceBaseEntityUtil.setSaveBaseEntityData(wmsAllocationOrder);
		wmsAllocationOrder.setAllocationStatus(WmsOrderStatusUtil.NOCONFIRM);
		// 保存调拨单数据
		wmsAllocationOrderDao.save(wmsAllocationOrder);
		List<WmsAllocationOrder> list = new ArrayList<WmsAllocationOrder>();
		list.add(wmsAllocationOrder);
		// 保存调拨单操作日志
		saveOrderLog(list, WmsOrderLogStatus.ADD.getOperation());
		return resultBean;
	}

	@Override
	public ResultBean itemDelete(List<WmsAllocationOrder> list) {
		ResultBean resultBean = new ResultBean(true);
		// 删除调拨单数据
		wmsAllocationOrderDao.batchDelete(list);

		// 保存操作日志
		saveOrderLog(list, WmsOrderLogStatus.UPDATE.getOperation());
		return resultBean;
	}

}
